データの変更が単独で起こることはほとんどありません。振替では一方の口座から引き落とし、もう一方の口座に入金する必要があり、注文では在庫を確保し、支払いを記録する必要があります。もしシステムが途中で停止すると、データベースは決して存在しなかった世界を表す状態になってしまいます。 トランザクション は、この問題に対するデータベースの答えです。つまり、データベースが次のように扱う1つ以上の操作の連続です。 単一の分割できない作業単位。
すべてか、まったくしないか
トランザクション内では、すべての操作が1つの結果に属します。データベースが、トランザクションの一部だけが実行された完了状態を外部にさらすことは決してありません。古典的な例は2つの銀行口座間の振替です。まず振替元口座の残高を減らし、次に振替先口座の残高を増やします。もし最初の手順だけが成功すれば、お金は消えてしまいます。2番目の手順だけが成功すれば、お金がどこからともなく現れてしまいます。両方の手順を1つのトランザクションにまとめることで、どちらの可能性も排除されます。
このオール・オア・ナッシングの保証は 原子性。 コミット とは、トランザクションの変更を永続化する行為です。コミットされないトランザクションは、まったく痕跡を残しません。 持続性 は最後のピースを加えます。コミットが戻った後は、その直後にマシンの電源が失われても、変更は保持されます。
トランザクションは境界である
トランザクションは、一連のステートメントを囲む境界としてイメージするとわかりやすいでしょう。境界の前でも後でも、データは構造が課す規則を満たしています。境界の内側には中間状態が存在します。一方の口座はすでに引き落とされているのに、もう一方の口座にはまだ入金されていない、という状態です。しかし、そうした状態はそのトランザクションだけに非公開です。他のセッションで後から実行されるステートメントは、それらを真実として扱いません。
同時に2つの役割
したがって、トランザクションには2つの役割があります。1つ目は 障害処理です。プロセスがクラッシュしたり、接続が切断されたり、ステートメントがエラーを発生させたりした場合、データベースはトランザクションが始まる前に存在していた状態を復元できます。2つ目は 可視性の制御です。作業が進行中の間、他の読み取り側は未完了の結果から遮断されます。これら2つの役割は関連していますが、同一ではありません。原子性は変更を保持するかどうかを決定し、可視性は分離性(アイソレーション)によって制御されます。分離性とは、同時実行されるトランザクション同士がどれだけ互いを見ることができるかを制御する設定です。
